/**
 * @ Author: luoqi
 * @ Create Time: 2024-10-13 22:33
 * @ Modified by: luoqi
 * @ Modified time: 2025-03-06 22:45
 * @ Description:
 */

#ifndef _QDRIVE_H
#define _QDRIVE_H

#include <bsp.h>
#include <stdbool.h>
#include "../modules/qfoc.h"

typedef enum {
    QDRV_LINK_CMD_SET_FOC_RMOD = 0x10,     // set foc run mode
    QDRV_LINK_CMD_SET_FOC_CMOD,             // set foc control mode
    QDRV_LINK_CMD_SET_FOC_I,                // set foc current
    QDRV_LINK_CMD_SET_FOC_V,                // set foc velocity
    QDRV_LINK_CMD_SET_FOC_P,                // set foc position
    QDRV_LINK_CMD_SET_FOC_IMAX,             // set foc current limit
    QDRV_LINK_CMD_SET_FOC_VMAX,             // set foc velocity limit

    QDRV_LINK_CMD_SET_FOC_FB_FRQ,           // set foc feedback frequency
    QDRV_LINK_CMD_SET_FOC_FB_TYPE,          // set foc feedback type
    QDRV_LINK_CMD_SET_FOC_FB_DEV,           // set foc feedback device
    QDRV_LINK_CMD_SET_FOC_ENABLE,           // enable device
    QDRV_LINK_CMD_SET_FOC_STOP,             // stop device
} QDrvLinkCmd;

typedef enum {
    QDRV_FB_TYPE_NONE = 0,
    QDRV_FB_TYPE_I,
    QDRV_FB_TYPE_V,
    QDRV_FB_TYPE_P,
} QDrvFbType;

typedef enum {
    QDRV_FB_I = 0x10,
    QDRV_FB_V,
    QDRV_FB_P,
    QDRV_FB_ERR,
} QDrvFbId; // feedback id lower 8 bits, higher 3 bits is device id

typedef enum {
    QDRV_FB_DEV_ALL = 0x00,
    QDRV_FB_DEV_FOC1,
    QDRV_FB_DEV_FOC2,
} QDrvFbDev;

typedef enum {
    PWM_CH1,
    PWM_CH2,
    PWM_CH3,
} PwmChannel;

typedef enum {
    FOC_DEV_1 = 0,
    FOC_DEV_2 = 1,
} FocDev;

typedef enum {
    QDRV_ERR_NONE = 0,
    
} QDrvErrCode;

#define QDRV_FOC1_VLOOP_FLAG    (1 << 0)
#define QDRV_FOC2_VLOOP_FLAG    (1 << 1)
#define QDRV_FOC1_PLOOP_FLAG    (1 << 2)
#define QDRV_FOC2_PLOOP_FLAG    (1 << 3)

typedef struct {
    QFocObj foc1;
    QFocObj foc2;

    PmsmMotor motor1;
    PmsmMotor motor2;

    TX_EVENT_FLAGS_GROUP foc_cloop_flags;

    uint32_t adc1_inj_cnt;
    uint32_t adc2_inj_cnt;
    uint32_t adc1_conv_cnt;
    uint32_t adc2_conv_cnt;
    
    uint16_t adc1_buf[3];
    uint16_t adc2_buf[3];
    float vbus;
    float vbus_bias;
    float temperature;

    bool foc1_axis_aligned;
    bool foc2_axis_aligned;

    QDrvErrCode ecode;
    uint8_t link_id;   // 0-7;
    uint32_t link_fb_frq;
    QDrvFbType link_fb_type;
    QDrvFbDev link_fb_dev;
} QDrive;

int qdrv_init(uint8_t id);

int foc_pwm_ch_set(FocDev dev, PwmChannel ch, uint16_t value);

int foc_pwm_set(FocDev dev, uint16_t pwma, uint16_t pwmb, uint16_t pwmc);

int foc_pwm_start(FocDev dev);

int foc_pwm_stop(FocDev dev);

QFocObj *foc_obj_get(FocDev dev);

QDrive *qdrv_get(void);

#endif
